/*
 * @Author: c
 * @Date: 2023-11-24 08:51:46
 * @LastEditTime: 2024-03-30 03:42:27
 * @LastEditors: c
 * @Description: 
 * @FilePath: \music-web-backend\src\app.module.ts
 * https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { ClassSerializerInterceptor, Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core';
import { MulterModule } from '@nestjs/platform-express';
import { ServeStaticModule } from '@nestjs/serve-static';
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
import envConfig from '../config/env';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigEnum } from './common/enums/config.enum';
import { AllExceptionsFilter } from './common/filters/all-exceptions.filter';
import { CacheInterceptor } from './common/interceptors/cache.interceptor';
import { ErrorsInterceptor } from './common/interceptors/exception.interceptor';
import { TransformInterceptor } from './common/interceptors/transform.interceptor';
import { AuthModule } from './core/system/auth/auth.module';
import { MenusModule } from './core/system/menus/menus.module';
import { RolesModule } from './core/system/roles/roles.module';
import { UserModule } from './core/system/user/user.module';
import { UserlogModule } from './core/system/userlog/userlog.module';
// import { CaslAbilityService } from './auth/casl-ability.service';
import { join } from 'path';
import { CaslModule } from './common/casl/casl.module';
import { multerOptions } from './common/const/constants';
import { VideoRate } from './common/entity/video.enity';
import { AlbumModule } from './core/music/album/album.module';
import { Album } from './core/music/album/entities/album.entity';
import { ArtistModule } from './core/music/artist/artist.module';
import { Artist } from './core/music/artist/entities/artist.entity';
import { AudioModule } from './core/music/audio/audio.module';
import { BannerModule } from './core/music/banner/banner.module';
import { CategoryModule } from './core/music/category/category.module';
import { Category } from './core/music/category/entities/category.entity';
import { Index } from './core/music/home/entities/home.entity';
import { HomeModule } from './core/music/home/home.module';
import { Picture } from './core/music/picture/entities';
import { PictureModule } from './core/music/picture/picture.module';
import { RateFileInfo } from './core/music/rate_file_info/entity/audio.enity';
import { SearchModule } from './core/music/search/search.module';
import { Song } from './core/music/song/entities/song.entity';
import { SongModule } from './core/music/song/song.module';
import { Track } from './core/music/track/entities/track.entity';
import { TrackModule } from './core/music/track/track.module';
import { TrackCate } from './core/music/track_cate/enitity/track_cate.entity';
import { Video } from './core/music/video/entities/video.entity';
import { VideoModule } from './core/music/video/video.module';
import { VipModule } from './core/music/vip/vip.module';
import { DictModule } from './core/system/dict/dict.module';
import { DictTypeModule } from './core/system/dict_type/dict_type.module';
import { FileInfo } from './core/system/minio/entities/file_info.entity';
import { MinioClientModule } from './core/system/minio/minio.module';
import { RoleMenu } from './core/system/roles/entities/role_menu.entity';
import { UserRole } from './core/system/user/entities/user_role.entity';





@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, 'images'),
      serveRoot: '/static', // 需要添加'/' 此处相当于添加前缀
    }),
    MulterModule.registerAsync({
      imports: [ConfigModule],
      useFactory: (config: ConfigService) => {
        return multerOptions
      },
      inject: [ConfigService],
    }),
    // MulterModule.register({
    //   storage: diskStorage({
    //     destination: join(__dirname, '../resources'),
    //     filename: (_, file, callback) => {
    //       const fileName = `${new Date().getTime() + extname(file.originalname)
    //         }`;
    //       return callback(null, fileName);
    //     },
    //   }),
    // }),
    ConfigModule.forRoot({
      isGlobal: true,  // 设置为全局
      envFilePath: [envConfig.path]
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => ({
        type: configService.get(ConfigEnum.DB_TYPE), // 数据库类型
        entities: [
          UserRole, RoleMenu, Video, VideoRate, RateFileInfo, Artist, Picture, Category, Album, Song, Track,
          FileInfo,
          TrackCate,
          Index
        ],  // 数据表实体
        host: configService.get(ConfigEnum.DB_HOST), // 主机，默认为localhost
        port: configService.get<number>(ConfigEnum.DB_PORT), // 端口号
        username: configService.get(ConfigEnum.DB_USER),   // 用户名
        password: configService.get(ConfigEnum.DB_PASSWD), // 密码
        database: configService.get(ConfigEnum.DB_DATABASE), //数据库名
        timezone: '+08:00', //服务器上配置的时区
        synchronize: configService.get(ConfigEnum.DB_SYNC), //根据实体自动创建数据库表， 生产环境建议关闭
        autoLoadEntities: true, //如果为true,将自动加载实体 forFeature()方法注册的每个实体都将自动添加到配置对象的实体数组中
        retryDelay: 1000, //重试连接数据库间隔
        retryAttempts: 15,//重试连接数据库的次数
        logging: ['error'],
        // logger: new DatabaseLogger(),
      }) as TypeOrmModuleOptions,
    }),
    RolesModule,
    MenusModule,
    UserlogModule,
    CaslModule,
    DictTypeModule,
    DictModule,
    AuthModule,
    UserModule,
    ArtistModule,
    PictureModule,
    BannerModule,
    TrackModule,
    CategoryModule,
    VideoModule,
    HomeModule,
    AlbumModule,
    SongModule,
    VipModule,
    AudioModule,
    MinioClientModule,
    SearchModule,
  ],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: APP_FILTER,
      useClass: AllExceptionsFilter //过滤处理异常--全局捕获异常
    },
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor
    },
    {
      provide: APP_INTERCEPTOR,
      useClass: ErrorsInterceptor //全局错误处理
    },
    {
      provide: APP_INTERCEPTOR,
      useClass: ClassSerializerInterceptor
    },
    {
      provide: APP_INTERCEPTOR,
      useClass: TransformInterceptor //转换请求参数或者响应返回值
    },
  ],
})
export class AppModule { }
